<template>
  <div
    ref="mapContainer"
    id="mapContainer"
    style="width: 100vw; height: 100vh"></div>

  <activity-panel>
    <el-button @click="drawTyphoon">开始</el-button>
  </activity-panel>
</template>

<script setup>
import { onMounted, nextTick, ref } from "vue";
// ol custom API
import useInitMap from "@/utils/ol/useInitMap";
// ol API
import { Vector as VectorLayer } from "ol/layer";
import { Vector as VectorSource } from "ol/source";
import Feature from "ol/Feature";
import { Point, LineString, Polygon } from "ol/geom";
import { Style, Circle, Fill, Stroke, Text } from "ol/style";
import Overlay from "ol/Overlay";

// 台风路径数据
import mockData from "./mockData.json";

useInitMap({
  target: "mapContainer",
  zoom: 6,
  onLoadEnd: onLoadEnd,
});

function onLoadEnd(map) {
  // drawTyphoon();
}

let timer, source, typhoonLayer;
async function drawTyphoon() {
  // 向温州台风网数据接口请求数据
  // const res = await fetch(
  //   "https://data.istrongcloud.com/v2/data/complex/202501.json?v=1750576498303"
  // );
  // const data = await res.json();

  let index = 0;

  timer && clearInterval(timer);
  source && source.clear();

  if (!typhoonLayer) {
    source = new VectorSource();
    typhoonLayer = new VectorLayer({
      id: "typhoonLayer",
      name: "台风路径_蝴蝶",
      source: source,
    });

    window.map.addLayer(typhoonLayer);
  }

  timer = setInterval(() => {
    if (index >= mockData.points.length) {
      clearInterval(timer);
      return;
    }

    const pointItem = mockData.points[index];
    const position = [pointItem.lng, pointItem.lat];
    const lastPointItem = index > 0 ? mockData.points[index - 1] : null;
    const lastPointPosition = lastPointItem
      ? [lastPointItem.lng, lastPointItem.lat]
      : null;

    // 绘制台风路径点
    const feature = new Feature({
      geometry: new Point(position),
    });

    const pointStyle = new Style({
      image: new Circle({
        fill: new Fill({
          color: judgeColorByWindLevel(pointItem.strong),
        }),
        stroke: new Stroke({
          color: "#000",
          width: 1,
        }),
        radius: 6,
      }),
    });

    if (index === 0) {
      pointStyle.setText(
        new Text({
          text: mockData.name,
          scale: 1.3,
          offsetY: 0,
          offsetX: 30,
          fill: new Fill({
            color: "#000",
          }),
        })
      );
    }

    feature.setStyle(pointStyle);

    feature.set("attribute", pointItem);
    source.addFeature(feature);

    // 绘制台风路径线
    if (index > 0) {
      const lineFeature = new Feature({
        geometry: new LineString([lastPointPosition, position]),
      });

      lineFeature.setStyle(
        new Style({
          stroke: new Stroke({
            color: "#595959",
          }),
        })
      );

      source.addFeature(lineFeature);
    }

    // 绘制台风风圈
    drawWindCircle(
      source,
      position,
      pointItem.radius7_quad,
      pointItem.radius7,
      7
    );
    drawWindCircle(
      source,
      position,
      pointItem.radius10_quad,
      pointItem.radius10,
      10
    );
    drawWindCircle(
      source,
      position,
      pointItem.radius12_quad,
      pointItem.radius12,
      12
    );

    // 绘制台风标识
    let typhoonFlag = window.map.getOverlayById("typhoonFlag");

    if (!typhoonFlag) {
      const typhoonFlagElement = document.createElement("div");
      typhoonFlagElement.className = "typhoon-flag";
      typhoonFlag = new Overlay({
        id: "typhoonFlag",
        name: "台风标识",
        element: typhoonFlagElement,
        positioning: "center-center",
        autoPan: true,
      });

      window.map.addOverlay(typhoonFlag);
    }

    typhoonFlag.setPosition(position);

    index++;
  }, 100);
}

function judgeColorByWindLevel(strong) {
  const flag = strong.split(/[\(\)]/)[1];

  const mapObj = {
    TD: "#02ff02", // 热带低压
    TS: "#0264ff", // 热带风暴
    STS: "#fffb05", // 强热带风暴
    TY: "#ffac05", // 台风
    STY: "#f00f00", // 强台风
    SuperTY: "#b10021", // 超强台风
  };
  return mapObj[flag];
}

/**
 * 绘制台风风圈
 * @param {VectorSource} source 图层数据源
 * @param {Array} center 中心点
 * @param {Object} radiusQuad 风圈半径对象
 * @param {Number} maxRadius 最大半径
 * @param { 7 | 10 | 12} level 风圈等级
 */
function drawWindCircle(source, center, radiusQuad, maxRadius, level) {
  let color = "#2196f329";
  let strokeColor = "#2196f3";
  let featureId = "windCircle7";
  switch (level) {
    case 10:
      color = "#ff980042";
      strokeColor = "#ff9800";
      featureId = "windCircle10";
      break;
    case 12:
      color = "#ff000042";
      strokeColor = "#ff0000";
      featureId = "windCircle12";
      break;
    default:
      break;
  }

  // 如果风圈已经存在，则删除
  const feature = source.getFeatureById(featureId);
  if (feature) {
    source.removeFeature(feature);
  }

  if (!maxRadius) return;

  const Configs = {
    CIRCLE_CENTER_X: center[0],
    CIRCLE_CENTER_Y: center[1],
    CIRCLE_R: {
      SE: radiusQuad.se / 100, //东南
      NE: radiusQuad.ne / 100, //东北
      NW: radiusQuad.nw / 100, //西北
      SW: radiusQuad.sw / 100, //西南
    },
  };
  const points = [];
  const _interval = 6;
  for (let i = 0; i < 360 / _interval; i++) {
    let _r = 0;
    let _ang = i * _interval;
    if (_ang > 0 && _ang <= 90) {
      _r = Configs.CIRCLE_R.NE;
    } else if (_ang > 90 && _ang <= 180) {
      _r = Configs.CIRCLE_R.SE;
    } else if (_ang > 180 && _ang <= 270) {
      _r = Configs.CIRCLE_R.SW;
    } else {
      _r = Configs.CIRCLE_R.SW;
    }

    const x = Configs.CIRCLE_CENTER_X + _r * Math.cos((_ang * Math.PI) / 180);
    const y = Configs.CIRCLE_CENTER_Y + _r * Math.sin((_ang * Math.PI) / 180);

    points.push([x, y]);
  }

  const polyFeature = new Feature({
    geometry: new Polygon([points]),
  });

  const style = new Style({
    fill: new Fill({
      color: color,
    }),
    //边框
    stroke: new Stroke({
      color: strokeColor,
      width: 1,
    }),
    image: new Circle({
      radius: 2,
      fill: new Fill({
        color: "#ff0000",
      }),
    }),
  });
  polyFeature.setId(featureId);
  polyFeature.setStyle(style);

  source.addFeature(polyFeature);

  return polyFeature;
}
</script>

<style>
@keyframes spin {
  0% {
    transform: rotate(0deg);
  }

  100% {
    transform: rotate(360deg);
  }
}

.typhoon-flag {
  width: 62px;
  height: 62px;
  background: url("./typhoon.png") no-repeat;
  animation: spin 0.5s linear infinite;
}
</style>
